<?php

namespace DataCube\DataCubeAggregation\Utils\Image;

class DatasetProcess
{
    /**
     * @throws \Exception Failed to process image
     */
    public static function getPixels(string $imageName, $type = 'rgb'): array
    {
        $pixelValues = array();
        // 加载图像文件
        if (!$ex = getimagesize($imageName)) {
            return [];
        }

        // 打开图片
        switch ($ex[2]) {
            case IMAGETYPE_JPEG:
            case IMAGETYPE_JPEG2000:
                if (!$image = imageCreateFromJpeg($imageName)) {
                    return [];
                }
                break;
            case IMAGETYPE_PNG:
                $image = imageCreateFromPng($imageName);
                break;
            case IMAGETYPE_GIF:
                $image = imageCreateFromGif($imageName);
                break;
            case IMAGETYPE_BMP:
                $image = imageCreateFromBmp($imageName);
                break;
            default :
                return [];
        }
        // false to load image
        if (false === $image) {
            throw new \Exception('Invalid');
        }
        // 获取图像宽度和高度  
        $width = imagesx($image);
        $height = imagesy($image);

        // 遍历图像的每个像素
        for ($y = 0; $y < $height; $y++) {
            for ($x = 0; $x < $width; $x++) {
                // 获取像素的RGB值  
                $rgb = imagecolorat($image, $x, $y);
                $color = imagecolorsforindex($image, $rgb);
                // 将RGB值存储到关联数组中
                if (strtolower($type) == 'argb') {
                    $pixelValues[$y][$x] = [$color['red'], $color['green'], $color['blue'], $color['alpha']];;
                } else {
                    $pixelValues[$y][$x] = [$color['red'], $color['green'], $color['blue']];;
                }
            }
        }
        return $pixelValues;
    }

    public static function getGray($img_path)
    {
        if (!$ex = getimagesize($img_path)) {
            return false;
        }

        // 打开图片
        switch ($ex[2]) {
            case IMAGETYPE_JPEG:
            case IMAGETYPE_JPEG2000:
                if (!$im = imageCreateFromJpeg($img_path)) {
                    return false;
                }
                break;
            case IMAGETYPE_PNG:
                $im = imageCreateFromPng($img_path);
                break;
            case IMAGETYPE_GIF:
                $im = imageCreateFromGif($img_path);
                break;
            case IMAGETYPE_BMP:
                $im = imageCreateFromBmp($img_path);
                break;
            default :
                return false;
        }

        $gray = array_fill(0, $ex[1],
            array_fill(0, $ex[0], 0)
        );

        // 转为灰阶图像
        foreach ($gray as $y => &$row) {
            foreach ($row as $x => &$Y) {
                $rgb = imagecolorat($im, $x, $y);
                // 根据颜色求亮度
                $B = $rgb & 255;
                $G = ($rgb >> 8) & 255;
                $R = ($rgb >> 16) & 255;
                $Y = ($R * 19595 + $G * 38469 + $B * 7472) >> 16;
            }
        }
        unset($row, $Y);

        // 自动求域值
        $back = 127;
        do {
            $crux = $back;
            $s = $b = $l = $I = 0;
            foreach ($gray as $row) {
                foreach ($row as $Y) {
                    if ($Y < $crux) {
                        $s += $Y;
                        $l++;
                    } else {
                        $b += $Y;
                        $I++;
                    }
                }
            }
            $s = $l ? floor($s / $l) : 0;
            $b = $I ? floor($b / $I) : 0;
            $back = ($s + $b) >> 1;
        } while ($crux != $back);

        // 二值化
        $bin = $gray;
        foreach ($bin as &$row) {
            foreach ($row as &$Y) {
                $Y = $Y < $crux ? 0 : 1;
            }
        }

        return array(
            $gray,
            $bin,
        );
    }
}
